<?php

namespace App\Jobs\Publish;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use App\Models\Entity\Column\Recommend;
use App\Models\Task\Task;
use Illuminate\Support\Facades\DB;
use Encore\Admin\Facades\Admin;

class RecommendJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    protected $ids;
    protected $option;
    public $tries = 1;
    public $timeout = 30;
    public $taskid;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($option, $ids='', $taskid='')
    {
        $this->option = $option;
        $this->ids    = $ids;
        $this->taskid = $taskid;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        switch ($this->option) {
            // 将全部发布任务分成若干个小任务
            case 1:
                $total_num         = 0;
                $publish_chunk_num = config('custom.base.job.recommend.publish_chunk_num');
                $up_and_publish    = config('custom.base.job.up_and_publish');
                Recommend::where($up_and_publish)->select('id')->chunk($publish_chunk_num, function($ids) use(&$total_num){
                    if(!empty($ids)){
                        $total_num += count($ids);
                        dispatch(new self(2, $ids, $this->taskid));
                    }
                });
                $total_num = ($total_num === 0) ? -1 : $total_num;
                self::updateTasks($this->taskid,['total_num' => $total_num]);
                break;
            // 每次处理500条记录的发布小任务
            case 2:
                $publish_small_chunk_num = config('custom.base.job.recommend.publish_small_chunk_num');
                foreach ($this->ids->chunk($publish_small_chunk_num) as $chunk_ids) {
                    $chunk_ids = $chunk_ids->pluck('id');
                    $recommends = Recommend::with(['vassetis'])->whereIn('id', $chunk_ids)->get();
                    $datas = [];
                    $data  = [];
                    foreach ($recommends as $recommend_key => $recommend_value) {
                        // 推荐位ID
                        $data['recommend_id'] = $recommend_value->id;
                        // 推荐位编号
                        // $data['recommend_no'] = $recommend_value->recommend_no;
                        // 专题名称
                        $data['name']         = $recommend_value->name;
                        // 专题标题
                        $data['title']        = $recommend_value->title;
                        // 副标题
                        $data['subtitle']     = $recommend_value->subtitle;
                        // 详情
                        $data['long_desc']    = $recommend_value->long_desc;
                        // 简述
                        $data['short_desc']   = $recommend_value->short_desc;
                        // 图片
                        $data['img']          = $recommend_value->img;
                        // 关联栏目列表
                        $data['collist_id']   = $recommend_value->collist_id;
                        // 关联栏目
                        $data['column_id']    = $recommend_value->column_id;
                        // 关联媒资
                        if ($recommend_value->vassetis->first()) {
                            $data['vassetis'] = json_encode($recommend_value->vassetis);
                        } else {
                            $data['vassetis'] = '';
                        }
                        $datas[]              = $data;
                    }
                    DB::connection('interface')->beginTransaction();
                    try {
                        DB::connection('interface')->table('recommends')->insert($datas);
                        DB::connection('interface')->commit();
                        self::updateRecommends($chunk_ids, ['publish_status' => 1]);
                        self::updateTasks($this->taskid, ['done_num' => DB::raw('done_num + '.count($chunk_ids))]);
                    } catch (\Exception $e) {
                        DB::connection('interface')->rollback(); //事务回滚
                        dd($e->getMessage());
                    }
                }
                break;
            // 将全部上线任务分成若干个小任务
            case 3:
                $total_num          = 0;
                $online_chunk_num   = config('custom.base.job.recommend.online_chunk_num');
                $down_and_published = config('custom.base.job.down_and_published');
                Recommend::where($down_and_published)->select('id')->chunk($online_chunk_num, function($ids) use(&$total_num){
                    if(!empty($ids)){
                        $total_num += count($ids);
                        dispatch(new self(4, $ids, $this->taskid));
                    }
                });
                $total_num = ($total_num === 0) ? -1 : $total_num;
                self::updateTasks($this->taskid, ['total_num' => $total_num]);
                break;
            // 每次处理5000条记录的上线小任务
            case 4:
                $user_id = self::getTasks($this->taskid,'user_id');
                self::updateRecommends($this->ids->pluck('id'), [
                    'online_status'       => 1, 
                    'publish_down_status' => 0, 
                    'user_id'             => $user_id, 
                    'online_at'           => date('Y-m-d H:i:s')
                ]);
                self::updateTasks($this->taskid, ['done_num' => DB::raw('done_num +'.count($this->ids))]);
                break;
            // 将全部下线任务分成若干个小任务
            case 5:
                $total_num         = 0;
                $offline_chunk_num = config('custom.base.job.recommend.offline_chunk_num');
                $up                = config('custom.base.job.up');
                Recommend::where($up)->select('id')->chunk($offline_chunk_num, function ($ids) use (&$total_num) {
                    if (!empty($ids)) {
                        $total_num += count($ids);
                        dispatch(new self(6, $ids, $this->taskid));
                    }
                });
                $total_num = ($total_num === 0) ? -1 : $total_num;
                self::updateTasks($this->taskid, ['total_num' => $total_num]);
                break;
            // 每次处理5000条记录的下线小任务
            case 6:
                $user_id = self::getTasks($this->taskid,'user_id');
                self::updateRecommends($this->ids->pluck('id'), [
                    'online_status'  => 0, 
                    'publish_status' => 0, 
                    'user_id'        => $user_id, 
                    'offline_at'     => date('Y-m-d H:i:s')
                ]);
                self::updateTasks($this->taskid, ['done_num' => DB::raw('done_num +' . count($this->ids))]);
                break;
            // 将下线发布任务分成若干个小任务
            case 7:
                // 如果是全部下线,则直接truncate表
                $up     = config('custom.base.job.up');
                $result = Recommend::where($up)->count();
                if ($result === 0) {
                    self::deleteRecommends('all');
                    $user_id = self::getTasks($this->taskid,'user_id');
                    self::updateRecommends('all', [
                        'publish_down_status' => 1, 
                        'user_id'             => $user_id, 
                    ]);
                    $total = Recommend::count();
                    self::updateTasks($this->taskid, ['total_num' => $total, 'done_num' => $total]);
                    return;
                }
                $total_num         = 0;
                $publish_chunk_num = config('custom.base.job.recommend.publish_chunk_num');
                $down_and_publish  = config('custom.base.job.down_and_publish');
                Recommend::where($down_and_publish)->select('id')->chunk($publish_chunk_num, function ($ids) use (&$total_num) {
                    if (!empty($ids)) {
                        $total_num += count($ids);
                        dispatch(new self(8, $ids, $this->taskid));
                    }
                });
                $total_num = ($total_num === 0) ? -1 : $total_num;
                self::updateTasks($this->taskid, ['total_num' => $total_num]);
                break;
            // 每次处理500条记录的下线发布小任务
            case 8:
                $user_id = self::getTasks($this->taskid,'user_id');
                self::deleteRecommends($this->ids->pluck('id'));
                self::updateRecommends($this->ids->pluck('id'), [
                    'publish_down_status' => 1, 
                    'user_id'             => $user_id, 
                ]);
                self::updateTasks($this->taskid, ['done_num' => DB::raw('done_num +' . count($this->ids))]);
                break;
        }
    }
 
        /**
     * 更新媒资表
     */
    public static function updateRecommends($ids, $data)
    {
        try {
            if ($ids === 'all') {
                return DB::table('recommends')->update($data);
            }
            return Recommend::whereIn('id', $ids)->update($data);
        } catch (\Exception $e) {
            dd($e->getMessage());
        }
    }
 
     /**
     * 删除接口库中媒资表
     */
    public static function deleteRecommends($ids)
    {
        try {
            if ($ids === 'all') {
                return DB::connection('interface')->table('recommends')->truncate();
            }
            return DB::connection('interface')->table('recommends')->whereIn('recommend_id', $ids)->delete();
        } catch (\Exception $e) {
            dd($e->getMessage());
        }
    }
 
    /**
     * 更新任务表
     */
    public static function updateTasks($id, $data)
    {
        try {
            return Task::where('id', $id)->update($data);
        } catch (\Exception $e) {
            dd($e->getMessage());
        }
    }

     /**
     * 获取tasks中的信息
     */
    public static function getTasks($id, $field)
    {
        try {
            return Task::where('id', $id)->value($field);
        } catch (\Exception $e) {
            dd($e->getMessage());
        }
    }
}
